import 'package:flutter/material.dart';

/**
 * 文件夹数据模型
 * 支持层级关系、拖拽排序和各种文件夹操作
 */
class FolderModel {
  final String id;
  final String name;
  final String? parentId;
  final List<String> childrenIds;
  final DateTime createdAt;
  final DateTime updatedAt;
  final Color? color;
  final IconData? icon;
  final int sortOrder;
  final bool isExpanded;
  final bool isPinned;
  final Map<String, dynamic>? metadata;

  const FolderModel({
    required this.id,
    required this.name,
    this.parentId,
    this.childrenIds = const [],
    required this.createdAt,
    required this.updatedAt,
    this.color,
    this.icon,
    this.sortOrder = 0,
    this.isExpanded = false,
    this.isPinned = false,
    this.metadata,
  });

  /**
   * 从JSON创建文件夹模型
   */
  factory FolderModel.fromJson(Map<String, dynamic> json) {
    return FolderModel(
      id: json['id'] as String,
      name: json['name'] as String,
      parentId: json['parentId'] as String?,
      childrenIds: List<String>.from(json['childrenIds'] ?? []),
      createdAt: DateTime.parse(json['createdAt'] as String),
      updatedAt: DateTime.parse(json['updatedAt'] as String),
      color: json['color'] != null ? Color(json['color'] as int) : null,
      icon: json['icon'] != null ? IconData(json['icon'] as int, fontFamily: 'MaterialIcons') : null,
      sortOrder: json['sortOrder'] as int? ?? 0,
      isExpanded: json['isExpanded'] as bool? ?? false,
      isPinned: json['isPinned'] as bool? ?? false,
      metadata: json['metadata'] as Map<String, dynamic>?,
    );
  }

  /**
   * 转换为JSON
   */
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'name': name,
      'parentId': parentId,
      'childrenIds': childrenIds,
      'createdAt': createdAt.toIso8601String(),
      'updatedAt': updatedAt.toIso8601String(),
      'color': color?.value,
      'icon': icon?.codePoint,
      'sortOrder': sortOrder,
      'isExpanded': isExpanded,
      'isPinned': isPinned,
      'metadata': metadata,
    };
  }

  /**
   * 复制并修改属性
   */
  FolderModel copyWith({
    String? id,
    String? name,
    String? parentId,
    List<String>? childrenIds,
    DateTime? createdAt,
    DateTime? updatedAt,
    Color? color,
    IconData? icon,
    int? sortOrder,
    bool? isExpanded,
    bool? isPinned,
    Map<String, dynamic>? metadata,
  }) {
    return FolderModel(
      id: id ?? this.id,
      name: name ?? this.name,
      parentId: parentId ?? this.parentId,
      childrenIds: childrenIds ?? this.childrenIds,
      createdAt: createdAt ?? this.createdAt,
      updatedAt: updatedAt ?? this.updatedAt,
      color: color ?? this.color,
      icon: icon ?? this.icon,
      sortOrder: sortOrder ?? this.sortOrder,
      isExpanded: isExpanded ?? this.isExpanded,
      isPinned: isPinned ?? this.isPinned,
      metadata: metadata ?? this.metadata,
    );
  }

  /**
   * 判断是否为根文件夹
   */
  bool get isRoot => parentId == null;

  /**
   * 判断是否有子文件夹
   */
  bool get hasChildren => childrenIds.isNotEmpty;

  /**
   * 获取层级深度
   */
  int getDepth(Map<String, FolderModel> allFolders) {
    if (isRoot) return 0;
    final parent = allFolders[parentId];
    if (parent == null) return 0;
    return parent.getDepth(allFolders) + 1;
  }

  /**
   * 获取所有祖先文件夹ID
   */
  List<String> getAncestorIds(Map<String, FolderModel> allFolders) {
    final ancestors = <String>[];
    String? currentParentId = parentId;
    
    while (currentParentId != null) {
      ancestors.add(currentParentId);
      final parent = allFolders[currentParentId];
      currentParentId = parent?.parentId;
    }
    
    return ancestors;
  }

  /**
   * 获取所有后代文件夹ID
   */
  List<String> getDescendantIds(Map<String, FolderModel> allFolders) {
    final descendants = <String>[];
    
    void collectDescendants(String folderId) {
      final folder = allFolders[folderId];
      if (folder != null) {
        for (final childId in folder.childrenIds) {
          descendants.add(childId);
          collectDescendants(childId);
        }
      }
    }
    
    collectDescendants(id);
    return descendants;
  }

  /**
   * 判断是否可以移动到指定父文件夹
   */
  bool canMoveTo(String? targetParentId, Map<String, FolderModel> allFolders) {
    // 不能移动到自己
    if (targetParentId == id) return false;
    
    // 不能移动到自己的子文件夹
    final descendants = getDescendantIds(allFolders);
    if (targetParentId != null && descendants.contains(targetParentId)) {
      return false;
    }
    
    return true;
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is FolderModel &&
        other.id == id &&
        other.name == name &&
        other.parentId == parentId &&
        other.childrenIds.length == childrenIds.length &&
        other.childrenIds.every((id) => childrenIds.contains(id)) &&
        other.createdAt == createdAt &&
        other.updatedAt == updatedAt &&
        other.color == color &&
        other.icon == icon &&
        other.sortOrder == sortOrder &&
        other.isExpanded == isExpanded &&
        other.isPinned == isPinned;
  }

  @override
  int get hashCode {
    return Object.hash(
      id,
      name,
      parentId,
      childrenIds,
      createdAt,
      updatedAt,
      color,
      icon,
      sortOrder,
      isExpanded,
      isPinned,
    );
  }

  @override
  String toString() {
    return 'FolderModel(id: $id, name: $name, parentId: $parentId, '
           'childrenCount: ${childrenIds.length}, depth: ${isRoot ? 0 : "unknown"})';
  }
}

/**
 * 文件夹树节点
 * 用于构建和操作文件夹树结构
 */
class FolderTreeNode {
  final FolderModel folder;
  final List<FolderTreeNode> children;
  final FolderTreeNode? parent;
  final int level;

  const FolderTreeNode({
    required this.folder,
    this.children = const [],
    this.parent,
    this.level = 0,
  });

  /**
   * 判断是否为叶子节点
   */
  bool get isLeaf => children.isEmpty;

  /**
   * 判断是否为根节点
   */
  bool get isRoot => parent == null;

  /**
   * 获取所有后代节点
   */
  List<FolderTreeNode> getAllDescendants() {
    final descendants = <FolderTreeNode>[];
    
    void collectDescendants(FolderTreeNode node) {
      for (final child in node.children) {
        descendants.add(child);
        collectDescendants(child);
      }
    }
    
    collectDescendants(this);
    return descendants;
  }

  /**
   * 查找指定ID的节点
   */
  FolderTreeNode? findNode(String folderId) {
    if (folder.id == folderId) return this;
    
    for (final child in children) {
      final found = child.findNode(folderId);
      if (found != null) return found;
    }
    
    return null;
  }

  /**
   * 获取路径字符串
   */
  String getPath() {
    if (isRoot) return folder.name;
    return '${parent!.getPath()}/${folder.name}';
  }

  @override
  String toString() {
    return 'FolderTreeNode(folder: ${folder.name}, level: $level, '
           'childrenCount: ${children.length})';
  }
}

/**
 * 文件夹操作类型
 */
enum FolderOperation {
  create,
  rename,
  move,
  delete,
  pin,
  unpin,
  expand,
  collapse,
  changeColor,
  changeIcon,
  reorder,
}

/**
 * 文件夹操作事件
 */
class FolderOperationEvent {
  final FolderOperation operation;
  final String folderId;
  final Map<String, dynamic>? data;
  final DateTime timestamp;

  const FolderOperationEvent({
    required this.operation,
    required this.folderId,
    this.data,
    required this.timestamp,
  });

  factory FolderOperationEvent.create({
    required FolderOperation operation,
    required String folderId,
    Map<String, dynamic>? data,
  }) {
    return FolderOperationEvent(
      operation: operation,
      folderId: folderId,
      data: data,
      timestamp: DateTime.now(),
    );
  }

  @override
  String toString() {
    return 'FolderOperationEvent(operation: $operation, folderId: $folderId, '
           'timestamp: $timestamp)';
  }
}

/**
 * 文件夹拖拽数据
 */
class FolderDragData {
  final String folderId;
  final String folderName;
  final int originalIndex;
  final String? originalParentId;

  const FolderDragData({
    required this.folderId,
    required this.folderName,
    required this.originalIndex,
    this.originalParentId,
  });

  @override
  String toString() {
    return 'FolderDragData(folderId: $folderId, folderName: $folderName, '
           'originalIndex: $originalIndex, originalParentId: $originalParentId)';
  }
}

/**
 * 文件夹排序类型
 */
enum FolderSortType {
  name,
  createdAt,
  updatedAt,
  sortOrder,
  custom,
}

/**
 * 文件夹排序方向
 */
enum FolderSortDirection {
  ascending,
  descending,
}

/**
 * 文件夹排序配置
 */
class FolderSortConfig {
  final FolderSortType sortType;
  final FolderSortDirection direction;
  final bool pinnedFirst;

  const FolderSortConfig({
    this.sortType = FolderSortType.name,
    this.direction = FolderSortDirection.ascending,
    this.pinnedFirst = true,
  });

  /**
   * 复制并修改配置
   */
  FolderSortConfig copyWith({
    FolderSortType? sortType,
    FolderSortDirection? direction,
    bool? pinnedFirst,
  }) {
    return FolderSortConfig(
      sortType: sortType ?? this.sortType,
      direction: direction ?? this.direction,
      pinnedFirst: pinnedFirst ?? this.pinnedFirst,
    );
  }

  @override
  String toString() {
    return 'FolderSortConfig(sortType: $sortType, direction: $direction, '
           'pinnedFirst: $pinnedFirst)';
  }
}